<?php
/**
 * This file defines the PHP class {@see \BF\ExplicitGetter}.
 *
 * @author   Kado <ulfikado@gmail.com>
 * @category Beluga PHP5.3+ Framework
 * @package  BF\Core
 * @since    2015-01-17 14:35
 * @version  0.1  
 */

namespace BF
{

   /**
    * If you extend youre class from this class, youre class becomes a automatic working magic get method for
    * read accessing the return values of all avialable getXyz methods by dynamic properties.
    *
    * For example: If youre class defines the two public get methods 'getFoo()' and 'getFooBar()' you can also
    * access the resulting return values with the dynamic properties $instance->foo and $instance->fooBar.
    *
    * But dont forget to document youre dyn. class properties with the @ property-read annotation
    *
    * @since v0.1
    */
   class ExplicitGetter
   {

      /**
       * The magic get method to let you access all getter methods by dynamic properties.
       *
       * @param  string $name The name of the required dynamic property.
       * @return mixed
       * @throws \LogicException If the property is unknown
       */
      public function __get( $name )
      {

         $getterName = null;

         // Trigger a exception if the method not exists.
         if ( ! $this->hasReadableProperty( $name, $getterName ) )
         {
            throw new \LogicException( 'No such property: ' . __CLASS__ . '$' . $name );
         }

         // Call the method by the dynamic way.
         return $this->$getterName();

      }

      /**
       * Magic isset implementation.
       *
       * @param  string $name The name of the required property.
       * @return boolean
       */
      public function __isset( $name )
      {
         return \method_exists( $this, 'get' . \ucfirst( $name ) );
      }

      /**
       * Returns, if a property with the defined name exists for read access.
       *
       * @param  string $name       The name of the property.
       * @param  string $getterName Returns the name of the associated get method, if method returns TRUE.
       * @return boolean
       */
      public function hasReadableProperty( $name, &$getterName )
      {
         $getterName = 'get' . \ucfirst( $name );
         return \method_exists( $this, $getterName );
      }

   }

}

